home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
games
/
breaksrc.arc
/
break.asm
Wrap
Assembly Source File
|
1988-10-09
|
9KB
|
283 lines
******************************************************************************
* *
* break.asm version 1.0 of 20 August 1988 (C) L.J.M. de Wit 1988 *
* *
* This software may be used and distributed freely if not used commercially *
* and the originator (me) is mentioned. *
* *
******************************************************************************
* character codes
tab equ 9
lf equ 10
cr equ 13
* GEMDOS & (X)BIOS stuff
gemdos equ 1
bios equ 13
xbios equ 14
ptermres equ $31
setexc equ 5
cconws equ 9
crawcin equ 7
super equ $20
pterm0 equ 0
pterm equ $4c
iorec equ 14
* divers
bpaglen equ $100
textlen equ 12
datalen equ 20
bsslen equ 28
intrupt equ -32 ; Code returned by interrupted programs
* iorec struct offsets; the buffer ptr. itself has offset 0
ibufsize equ 4
ibufhead equ 6
ibuftl equ 8
ibuflow equ 10
ibufhi equ 12
brkinit:
move.l 4(sp),a0
adda.w #$80,a0 ; a0 points to argument string start
moveq.l #0,d0
move.b (a0)+,d0 ; Get string length &
clr.b (a0,d0.w) ; ensure '\0' termination
nxtbyt:
move.b (a0)+,d0
beq nxtdone ; '\0' char is end of string
cmp.b #'A',d0
blt.s arge
cmp.b #'Z',d0
bgt.s arge
or.b #$20,d0 ; Convert uppercase to lower
arge:
cmp.b #'e',d0 ; enable
bne.s argd
st enabled ; enabled = TRUE
bra.s nxtbyt
argd:
cmp.b #'d',d0 ; disable
bne.s argi
sf enabled ; enabled = FALSE
bra.s nxtbyt
argi:
cmp.b #'i',d0 ; input
bne.s argc
move.l a0,-(sp)
pea.l inpmsg
move.w #cconws,-(sp)
trap #gemdos ; Prompt for break char
addq.l #6,sp
move.w #crawcin,-(sp)
trap #gemdos ; Read the char
addq.l #2,sp
move.l d0,breakcode ; and store it
pea.l retmsg
move.w #cconws,-(sp)
trap #gemdos ; Print a cr/lf
addq.l #6,sp
move.l (sp)+,a0
bra.s nxtbyt
argc:
cmp.b #'c',d0 ; code of break char in hex
bne.s argz
moveq.l #0,d1 ; d1 will contain the code
argcnxt:
move.b (a0)+,d0
bne.s argcnz ; Not end of arg string yet
move.l d1,breakcode ; If end, store break char
bra nxtdone ; and goto end of arg string interpretation
argcnz:
cmp.b #' ',d0 ; End of number found
beq.s argcend
cmp.b #tab,d0 ; this one too
beq.s argcend
cmp.b #'0',d0 ; Now follows a series of tests and
blt.s userr ; conversions to find the hex digit's value.
cmp.b #'a',d0
blt.s argcnlc
sub.w #32,d0 ; convert lower case to upper
argcnlc:
cmp.b #'F',d0
bgt.s userr
cmp.b #'9',d0
ble.s argcnum
cmp.b #'A',d0
blt.s userr
subq.l #7,d0 ; Make up for diff between '9' and 'A'
argcnum:
sub.b #'0',d0 ; '0' is the base: 0
asl.l #4,d1 ; Multiply by 16
or.b d0,d1 ; OR in the 4 low digits of d0 into d1
bra.s argcnxt
argcend:
move.l d1,breakcode ; Store the break key code
bra nxtbyt
argz:
cmp.b #'z',d0
bne.s argsep
st zeroed ; Set the 'zeroed' flag
bra nxtbyt
argsep:
cmp.b #' ',d0 ; Accept space
beq nxtbyt
cmp.b #tab,d0 ; and tab
beq nxtbyt
cmp.b #'-',d0 ; and hyphen as separators (not strictly)
beq nxtbyt
userr:
pea.l usemsg ; If error in arg string show usage message
move.w #cconws,-(sp)
trap #gemdos
addq.l #6,sp
move.w #1,-(sp)
move.w #pterm,-(sp)
trap #gemdos ; and terminate with error status
nxtdone:
move.w #1,-(sp)
move.w #iorec,-(sp)
trap #xbios
addq.l #4,sp
move.l d0,iop ; Save pointer to iorec struct
move.l #-1,-(sp)
move.w #$46,-(sp)
move.w #setexc,-(sp)
trap #bios
addq.l #8,sp
move.l d0,oldvec ; Save old keyboard interrupt vector
lea.l breakey,a0
sub.l a0,d0
move.l d0,diff ; dist between start of old and new
clr.l -(sp)
move.w #super,-(sp)
trap #gemdos ; Supervisor mode
addq.l #2,sp
move.l d0,(sp)
lea.l magic,a0 ; a0 points to 'magic' string in this prog
move.l diff,d0
lea.l (a0,d0.l),a1 ; a1 points (perhaps) to 'magic' in old
move.l #(magicend-magic-1),d0 ; # chars in 'magic' string - 1
chkmag:
cmp.b (a0)+,(a1)+ ; Check strings for equality
dbne d0,chkmag
beq.s mageq ; If old prog DID contain magic string; else:
magne:
move.w #super,-(sp)
trap #gemdos ; Back to user mode (sp was still on stack)
addq.l #6,sp
clr.l diff ; First incarnation: will be made resident
pea.l breakey ; breakey will be new keyboard int. vector
move.w #$46,-(sp)
move.w #setexc,-(sp)
trap #bios ; Set it
addq.l #8,sp
move.l 4(sp),a0 ; basepage start
move.l #bpaglen,d0 ; base page length
add.l textlen(a0),d0 ; + text length
add.l datalen(a0),d0 ; + data length
add.l bsslen(a0),d0 ; + bss length
clr.w -(sp) ; return value: 0 for success
move.l d0,-(sp) ; # bytes to keep
move.w #ptermres,-(sp) ; keep process
trap #gemdos ; stops here...
mageq:
move.w #super,-(sp) ; second run of this program
trap #gemdos ; Back to user mode
addq.l #6,sp
move.l diff,d0
lea.l enabled,a0
move.b (a0),(a0,d0.l) ; Copy 'enabled' into old image
lea.l zeroed,a0
move.b (a0),(a0,d0.l) ; Do this too for 'zeroed'
lea.l breakcode,a0
move.l (a0),(a0,d0.l) ; And also for the current break char
move.w #pterm0,-(sp)
trap #gemdos ; Exits here with 0 as status.
breakey:
* The new interrupt routine
pea.l breaketc ; Return to breaketc after executing old code
move.w sr,-(sp) ; This is because old code ends with 'rte'
move.l oldvec,-(sp) ; Push old vector onto stack
rts ; and jump to it
breaketc:
tst.b enabled
beq dorte ; If not enabled do nothing
movem.l d0-d1/a0-a2,-(sp)
move.l iop,a0
move.w ibuftl(a0),d0
cmp.w ibufhead(a0),d0
beq.s dontbreak ; If empty keyboard buffer do nothing
move.l (a0),a1
move.l (a1,d0.w),d1 ; get the last entry
and.l #$00ff00ff,d1 ; mask only scan & ASCII part
cmp.l breakcode,d1 ; check against break code
beq.s normalbrk
cmp.l hardbreak,d1 ; check against stronger break code
bne.s dontbreak
moveq.l #-1,d1 ; make long negative - means hard break
normalbrk:
tst.b zeroed ; we have a break; is 'zeroed' flag set?
bne.s dozeroed
subq.w #4,d0 ; DECREMENT d0 with wrap
bpl.s wrapdone
add.w ibufsize(a0),d0
wrapdone:
move.w d0,ibuftl(a0)
bra.s gotbreak
dozeroed:
move.w ibuftl(a0),ibufhead(a0) ; Clear the entire buffer
gotbreak:
tst.l d1 ; hard break?
bmi.s dobreak
btst.b #5,20(sp) ; test Super bit on stacked SR
bne.s dontbreak
dobreak:
movem.l (sp)+,d0-d1/a0-a2
move.l #stop,2(sp) ; Return will be to the routine 'stop'
rte
dontbreak:
movem.l (sp)+,d0-d1/a0-a2
dorte:
rte
stop:
move.w #intrupt,-(sp) ; Code for interrupted programs
move.w #pterm,-(sp)
trap #gemdos ; and stop here
* section s.data
iop: dc.l 0 ; Pointer to iorec struct
breakcode: dc.l $002E0000 ; Defau